//ECE 476 FINAL Project "Air Jam"
//Guitar Chord Player
//Yuan Ning and Adam Beece
//Spring 2007

#include <mega32.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define begin {
#define end   }
#define int2fix(a)   (((int)(a))<<8)            //Convert char to fix. a is a char
#define fix2int(a)   ((signed char)((a)>>8))    //Convert fix to char. a is an int
#define float2fix(a) ((int)((a)*256.0))
#define fix2float(a) ((float)(a)/256.0)
#define countMAX 2000  //corresponding to .2 seconds
#define count2MAX 8 //corresponding to 1 ms 
#define count3MAX 80 //sampling frequency of Accelerometer 10 ms
#define waitMAX 100 //amount of time in ms to wait after successfully strumming (min strum time)
unsigned char strDelay; //multiples of 1ms typical values: 8,18 or 40 ms
unsigned char strLEDelay, strADelay, strDDelay, strGDelay, strBDelay, strHEDelay; //delay time between each string

char DelayLengthG,DelayLengthA,DelayLengthLE,DelayLengthD,upStrum,dnStrum,shiftedPA; //vector DelayLengths for each string, up/down strum flags and shifted input of accelerometer and flex sensors
int outputLE,outputA,outputD,outputG,outputB,outputHE; //output values for each string
unsigned int counterLE,counterA,counterD,counterG,counterB,counterHE; // counter used for the initial noise burst used in DDS. 

#pragma regalloc-
char DelayLengthHE; // we force these DelayLengths into memory to avoid collisions
char DelayLengthB;
#pragma regalloc+

//frequency/delay length lookup tables for six strings for up to 12th fret including open string
char strLE[13];
char strA[13];
char strD[13];
char strG[13];
char strB[13];
char strHE[13];

//initialize chords
char chord[6];//current chord
char chords[32][6]; //up to 32 chords, 6 chars within each chord controls fretting positions of 6 strings
//initialize chords

int burst[94];//signal buffer, this corresponds to a burst of noise used in Karplus Strong algorithm
//Since the maximum delay length for each string is different we initialize different vector lengths to conserve memory
int DelayLE[94];//DelayLine for LE
int DelayA[71];
int DelayD[53];
//int DelayG[39];
int DelayG[94];
int DelayB[31];
int DelayHE[23];

unsigned char inLE,inB,inG,inD,inA,inHE,outLE,outB,outG,outD,outA,outHE;  //indexes into said buffer
unsigned char mute; //low 6 bits controls which strings are muted, its a bit is 0 its muted

char output;   //flag used to determine if anything needs to be outputed
                    // 0 = no output, 1 = burst of "noise", 2 = no noise
unsigned char i,adcout,play;  //loop counter and adc output variables
unsigned int waittime;  //time to wait before checking an ADC for output, incremented by count 2;

unsigned int count,time,count2,count3,time2,time3;   //to handle timming

 interrupt [TIM2_OVF] void sgen(void)
 begin
   count--; //decremet counters
   count2--;
   count3--;
  
   if (count ==0) begin count = countMAX; time++; end //incremet time steps
   if (count2 == 0)
   begin
     count2 = count2MAX; 
     time2++;
     if (waittime>0) waittime--; //wait time is used in to debounce the accelerometer
     //else ADCSR.6 = 1;
   end
   if (count3 == 0) begin
         count3 = count3MAX;
         time3++;
   end

  if ((play == 0) && (waittime==0)) 
  begin
    adcout = ADCH;
    //ADCSR.6 = 1; 

    if (adcout > 110) //threshold of ADC: adcout = voltage output * 51.  
      begin 
      play = adcout;
      /*strDelay = (158-adcout);  //This part is for variable delay time between each string. I commented it out for the demo.
    	 strADelay = strDelay;
	 strDDelay = strDelay<<1;
	 strGDelay = strDelay*3;
	 strBDelay = strDelay<<2;
	 strHEDelay = strDelay*5;*/

      end
  end  
  else adcout = 0;
  if (waittime<2)
    ADCSR.6 = 1; //sample ADC

   if(output>0 && dnStrum)  //If we want to output a sound and it is a down strum
   begin
       
       /*
	This is the heart of the Karplus Strong algorithm: For each string we first see if it is time to play the string 
	(since this is a down strum LE is always played). When time2 is greater than a string's delay time. We 
            start the synthesis. The indices 'out' and 'in' are used to avoid shifting of whole delay vectors. For the 
	initial input a burst of noise, we add the noise and the average value of the last two values within the 
	delay vector and then put this value at the beginning of the delay line. Once the burst is gone we simply
	average the last two values of the delay line and place this value at the begining of the delay line. 
       */

        //LE String  
       if(1) //check to see if bit 0 (LE string) is high
       begin

         if(counterLE<DelayLengthLE) //Checking for the end of the noise burst
         begin
           if(outLE == 0)
           outputLE = burst[counterLE] + (DelayLE[outLE] + DelayLE[DelayLengthLE - 1])>>1; //wrap around of 'out' index
           else
           outputLE = burst[counterLE] + (DelayLE[outLE] + DelayLE[outLE - 1])>>1; 
           counterLE++; 
         end
         else // when the burst is gone we simply average the last two values of the delay line
         begin 
           if(outLE == 0)
           outputLE = (DelayLE[outLE] + DelayLE[DelayLengthLE - 1])>>1; 
           else
           outputLE = ( DelayLE[outLE] + DelayLE[outLE -1])>>1;
         end
         DelayLE[inLE] = outputLE; // delaying the output by the length of the delay line
    
         //update indices
         if (inLE == 0) begin inLE = DelayLengthLE-1; output = 2; end 
         else inLE--;
         if (outLE == 0) outLE = DelayLengthLE-1;
         else outLE--;

       end //end LE String
       
       /*
	The rest of the strings are sythesized in a similar mannor as the LE string
       */

       //A String
       if(time2>strADelay) //check to see if bit 0 (A string) is high
       begin

         if(counterA<DelayLengthA)
         begin
           if(outA == 0)
           outputA = burst[counterA] + (DelayA[outA] + DelayA[DelayLengthA-1])>>1;
           else
           outputA = burst[counterA] + (DelayA[outA] + DelayA[outA - 1])>>1;

           counterA++;
         end
         else
         begin
           if(outA == 0)
           outputA = (DelayA[outA] + DelayA[DelayLengthA-1])>>1;
           else
           outputA = (DelayA[outA] + DelayA[outA -1])>>1;
         end
         DelayA[inA] = outputA;

         if (inA == 0) begin inA = DelayLengthA-1; output = 2; end
         else inA--;
         if (outA == 0) outA = DelayLengthA-1;
         else outA--;
       end //end A String

       //D String
       if(time2>strDDelay) //check to see if bit 0 (A string) is high
       begin

         if(counterD<DelayLengthD)
         begin
           if(outD==0)
           outputD = burst[counterD] + (DelayD[outD] + DelayD[DelayLengthD - 1])>>1;
           else
           outputD = burst[counterD] + (DelayD[outD] + DelayD[outD - 1])>>1;

           counterD++;
         end
         else
         begin
           if(outD==0)
           outputD = (DelayD[outD] + DelayD[DelayLengthD - 1])>>1;
           else
           outputD = (DelayD[outD] + DelayD[outD - 1])>>1;
         end

         DelayD[inD] = outputD;

         if (inD == 0) begin inD = DelayLengthD-1; output = 2; end
         else inD--;
         if (outD == 0) outD = DelayLengthD-1;
         else outD--;
       end //end A String

       //G String
       if(time2>strGDelay) //check to see if bit 0 (A string) is high
       begin

         if(counterG<DelayLengthG)
         begin
           if(outG==0)
           outputG = burst[counterG] + (DelayG[outG] + DelayG[DelayLengthG - 1])>>1;
           else
           outputG = burst[counterG] + (DelayG[outG] + DelayG[outG - 1])>>1;
         counterG++;
         end
         else
         begin
           if(outG==0)
           outputG = (DelayG[outG] + DelayG[DelayLengthG - 1])>>1;
           else
           outputG = (DelayG[outG] + DelayG[outG - 1])>>1;
         end
         DelayG[inG] = outputG;

         if (inG == 0) begin inG = DelayLengthG-1; output = 2; end
         else inG--;
         if (outG == 0) outG = DelayLengthG-1;
         else outG--;
       end //end G String

       //B String
       if(time2>strBDelay) //check to see if bit 0 (B string) is high
       begin

         if(counterB<DelayLengthB)
         begin
           if(outB==0)
           outputB = burst[counterB] + (DelayB[outB] + DelayB[DelayLengthB - 1])>>1;
           else
           outputB = burst[counterB] + (DelayB[outB] + DelayB[outB - 1])>>1;
           counterB++;
         end
         else
         begin
           if(outB==0)
           outputB = (DelayB[outB] + DelayB[DelayLengthB - 1])>>1;
           else
           outputB = (DelayB[outB] + DelayB[outB - 1])>>1;
           counterB++;
         end
         DelayB[inB] = outputB;

         if (inB == 0) begin inB = DelayLengthB-1; output = 2; end
         else inB--;
         if (outB == 0) outB = DelayLengthB-1;
         else outB--;
       end //end B String

       //HE String
       if(time2>strHEDelay) //check to see if bit 0 (B string) is high
       begin

         if(counterHE<DelayLengthHE)
         begin
           if(outHE == 0)
           outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;//outputHE = burst[counterHE] + OnePoleLow(OnePoleLow(DelayHE[outHE]));outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;
           else
           outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[outHE - 1])>>1;//outputHE = burst[counterHE] + OnePoleLow(OnePoleLow(DelayHE[outHE]));//outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[outHE - 1])>>1;
           counterHE++;
         end
         else
         begin
           if(outHE == 0)
           outputHE = (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;//outputHE = OnePoleLow((OnePoleLow(DelayHE[outHE])));//
           else
           outputHE = (DelayHE[outHE] + DelayHE[outHE - 1])>>1;//outputHE = OnePoleLow((OnePoleLow(DelayHE[outHE])));//
         end

         DelayHE[inHE] = outputHE;

         if (inHE == 0) begin inHE = DelayLengthHE-1; output = 2; end
         else inHE--;
         if (outHE == 0) outHE = DelayLengthHE-1;
         else outHE--;

       end //end HE String

     if (1)
     begin
    
     // To more closely model strumming done on a real guitar
     // The higher strings are suppose to be quieter than the lower strings
     // because musicians usally strum the the top strings harder than the bottom ones. 
     outputLE = outputLE>>1;

     outputA = outputA>>1;

     outputD = outputD>>2;

     outputG = outputG>>2;

     outputB = outputB>>3;

     outputHE = outputHE>>3;

     //Zero outputs if a string is muted 
     if(chord[0] == 0)
     outputLE = 0;
     if(chord[1] ==0)
     outputA = 0;
     if(chord[2] ==0)
     outputD = 0;
     if(chord[3] == 0)
     outputG = 0;
     if(chord[4] == 0)
     outputB = 0;
     if(chord[5] == 0)
     outputHE = 0;

     //We add one more waveform to the output every strDelay length of time 
     if(time2>strHEDelay)
     OCR0 = fix2int((outputLE + outputA + outputD +outputG + outputB+outputHE))+128;
     else if(time2>strBDelay)
     OCR0 = fix2int((outputLE + outputA + outputD +outputG + outputB))+128;
     else if(time2>strGDelay)
     OCR0 = fix2int((outputLE + outputA + outputD +outputG ))+128;
     else if(time2>strDDelay)
     OCR0 = fix2int((outputLE + outputA + outputD ))+128;
     else if((time2>strADelay))
     OCR0 = fix2int((outputLE + outputA ))+128;
     else if (1)
     OCR0 = fix2int((outputLE ))+128;

     end

   end//if(output>0)

   //upStrum is identical to dnStrum except we play HE string first
   else if(output>0 && upStrum)    begin

             //LE String
       if((time2>strHEDelay)&&(chord[0]!=0)) //check to see if bit 0 (LE string) is high
       begin

         if(counterLE<DelayLengthLE)
         begin
           if(outLE == 0)
           outputLE = burst[counterLE] + (DelayLE[outLE] + DelayLE[DelayLengthLE - 1])>>1;
           else
           outputLE = burst[counterLE] + (DelayLE[outLE] + DelayLE[outLE - 1])>>1;
           counterLE++;
         end
         else
         begin
           if(outLE == 0)
           outputLE = (DelayLE[outLE] + DelayLE[DelayLengthLE - 1])>>1;
           else
           outputLE = ( DelayLE[outLE] + DelayLE[outLE -1])>>1;
         end
         DelayLE[inLE] = outputLE;

         if (inLE == 0) begin inLE = DelayLengthLE-1; output = 2; end
         else inLE--;
         if (outLE == 0) outLE = DelayLengthLE-1;
         else outLE--;

       end //end LE String

       //A String
       if((time2>strBDelay)&&(chord[1]!=0)) //check to see if bit 0 (A string) is high
       begin

         if(counterA<DelayLengthA)
         begin
           if(outA == 0)
           outputA = burst[counterA] + (DelayA[outA] + DelayA[DelayLengthA-1])>>1;
           else
           outputA = burst[counterA] + (DelayA[outA] + DelayA[outA - 1])>>1;

           counterA++;
         end
         else
         begin
           if(outA == 0)
           outputA = (DelayA[outA] + DelayA[DelayLengthA-1])>>1;
           else
           outputA = (DelayA[outA] + DelayA[outA -1])>>1;
         end
         DelayA[inA] = outputA;

         if (inA == 0) begin inA = DelayLengthA-1; output = 2; end
         else inA--;
         if (outA == 0) outA = DelayLengthA-1;
         else outA--;
       end //end A String

       //D String
       if((time2>strGDelay)&&(chord[2]!=0)) //check to see if bit 0 (A string) is high
       begin

         if(counterD<DelayLengthD)
         begin
           if(outD==0)
           outputD = burst[counterD] + (DelayD[outD] + DelayD[DelayLengthD - 1])>>1;
           else
           outputD = burst[counterD] + (DelayD[outD] + DelayD[outD - 1])>>1;

           counterD++;
         end
         else
         begin
           if(outD==0)
           outputD = (DelayD[outD] + DelayD[DelayLengthD - 1])>>1;
           else
           outputD = (DelayD[outD] + DelayD[outD - 1])>>1;
         end

         DelayD[inD] = outputD;

         if (inD == 0) begin inD = DelayLengthD-1; output = 2; end
         else inD--;
         if (outD == 0) outD = DelayLengthD-1;
         else outD--;
       end //end A String

       //G String
       if((time2>strDDelay)&&(chord[3]!=0)) //check to see if bit 0 (A string) is high
       begin

         if(counterG<DelayLengthG)
         begin
           if(outG==0)
           outputG = burst[counterG] + (DelayG[outG] + DelayG[DelayLengthG - 1])>>1;
           else
           outputG = burst[counterG] + (DelayG[outG] + DelayG[outG - 1])>>1;
         counterG++;
         end
         else
         begin
           if(outG==0)
           outputG = (DelayG[outG] + DelayG[DelayLengthG - 1])>>1;
           else
           outputG = (DelayG[outG] + DelayG[outG - 1])>>1;
         end
         DelayG[inG] = outputG;

         if (inG == 0) begin inG = DelayLengthG-1; output = 2; end
         else inG--;
         if (outG == 0) outG = DelayLengthG-1;
         else outG--;
       end //end G String

       //B String
       if((time2>strADelay)&&(chord[4]!=0)) //check to see if bit 0 (B string) is high
       begin

         if(counterB<DelayLengthB)
         begin
           if(outB==0)
           outputB = burst[counterB] + (DelayB[outB] + DelayB[DelayLengthB - 1])>>1;
           else
           outputB = burst[counterB] + (DelayB[outB] + DelayB[outB - 1])>>1;
           counterB++;
         end
         else
         begin
           if(outB==0)
           outputB = (DelayB[outB] + DelayB[DelayLengthB - 1])>>1;
           else
           outputB = (DelayB[outB] + DelayB[outB - 1])>>1;
           counterB++;
         end
         DelayB[inB] = outputB;

         if (inB == 0) begin inB = DelayLengthB-1; output = 2; end
         else inB--;
         if (outB == 0) outB = DelayLengthB-1;
         else outB--;
       end //end B String

       //HE String
       if(chord[5]!=0) //check to see if bit 0 (B string) is high
       begin

         if(counterHE<DelayLengthHE)
         begin
           if(outHE == 0)
           outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;//outputHE = burst[counterHE] + OnePoleLow(OnePoleLow(DelayHE[outHE]));outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;
           else
           outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[outHE - 1])>>1;//outputHE = burst[counterHE] + OnePoleLow(OnePoleLow(DelayHE[outHE]));//outputHE = burst[counterHE] + (DelayHE[outHE] + DelayHE[outHE - 1])>>1;
           counterHE++;
         end
         else
         begin
           if(outHE == 0)
           outputHE = (DelayHE[outHE] + DelayHE[DelayLengthHE-1])>>1;//outputHE = OnePoleLow((OnePoleLow(DelayHE[outHE])));//
           else
           outputHE = (DelayHE[outHE] + DelayHE[outHE - 1])>>1;//outputHE = OnePoleLow((OnePoleLow(DelayHE[outHE])));//
         end

         DelayHE[inHE] = outputHE;

         if (inHE == 0) begin inHE = DelayLengthHE-1; output = 2; end
         else inHE--;
         if (outHE == 0) outHE = DelayLengthHE-1;
         else outHE--;

       end //end HE String

     //+ outputD + outputG + outputB + outputHE+ outputA + outputD + outputG

     if (1)
     begin
     /*
     if(outputLE>21 | outputLE<-21)
     outputLE = outputLE>>1;
     if(outputA>21 | outputA<-21)
     outputA = outputA>>1;
     if(outputD>21 | outputD<-21)
     outputD = outputD>>1;
     if(outputG>21 | outputG<-21)
     outputG = outputG>>1;
     if(outputB>21 | outputB<-21)
     outputB = outputB>>1;
     if(outputHE>21 | outputHE<-21)
     outputHE = outputHE>>1;
     */
     
     if(chord[0]!=0)
     outputLE = outputLE>>1;
     if(chord[1]!=0)
     outputA = outputA>>1;
     if(chord[2]!=0)     
     outputD = outputD>>2;
     if(chord[3]!=0)
     outputG = outputG>>2;
     if(chord[4]!=0)
     outputB = outputB>>3;
     if(chord[5]!=0)
     outputHE = outputHE>>3;

     if(chord[0] == 0)
     outputLE = 0;
     if(chord[1] ==0)
     outputA = 0;
     if(chord[2] ==0)
     outputD = 0;
     if(chord[3] == 0)
     outputG = 0;
     if(chord[4] == 0)
     outputB = 0;
     if(chord[5] == 0)
     outputHE = 0;

     //OCR0 = fix2int((outputLE + outputA+outputD+outputG+outputB+outputHE ))+128;
     //OCR0 = fix2int(outputHE>>1)+128;

     if(time2>strHEDelay)
     OCR0 = fix2int((outputLE + outputA + outputD +outputG + outputB+outputHE))+128;
     else if(time2>strBDelay)
     OCR0 = fix2int((outputHE + outputA + outputD +outputG + outputB))+128;
     else if(time2>strGDelay)
     OCR0 = fix2int((outputHE + outputB + outputG +outputD ))+128;
     else if(time2>strDDelay)
     OCR0 = fix2int((outputHE + outputB + outputG ))+128;
     else if(time2>strADelay)
     OCR0 = fix2int((outputHE + outputB ))+128;
     else if (1)
     OCR0 = fix2int((outputHE ))+128;

     end

   end//if(output>0)

   else
       OCR0 = 128;

   //OCR0++;

 end  //ISR

///////////////////////////////////////////////////////////////////////////////

//Change TIMSK;
//TCCR2 = 0b00000010 sets T2 to overflow w/frequency 8 kHz
//T2 overflow reset OCR0 to update output, and so on
//T2 oveflow rate is the sampling rate.

void main(void)
begin

/*initialize lookup tables for DelayLine lengths that correspond 
  to the frequency of every note playable on an acoustic guitar
  for the first 12 frets. 
*/
strLE[0]=     94;
strLE[1]=     89;
strLE[2]=     84;
strLE[3]=     79;
strLE[4]=     75;
strLE[5]=     71;
strLE[6]=     67;
strLE[7]=     63;
strLE[8]=     59;
strLE[9]=     56;
strLE[10]=    53;
strLE[11]=    50;
strLE[12]=    47;

//DelayLengthA =

strA[0]=    71;
strA[1]=    67;
strA[2]=    63;
strA[3]=    59;
strA[4]=    56;
strA[5]=    53;
strA[6]=    50;
strA[7]=    47;
strA[8]=    44;
strA[9]=    42;
strA[10]=   39;
strA[11]=   37;
strA[12]=   35;

//DelayLengthD =

strD[0]=    53;
strD[1]=    50;
strD[2]=    47;
strD[3]=    44;
strD[4]=    42;
strD[5]=    39;
strD[6]=    37;
strD[7]=    35;
strD[8]=    33;
strD[9]=    31;
strD[10]=   29;
strD[11]=   28;
strD[12]=   26;

//DelayLengthG =

strG[0]=    39;
strG[1]=    37;
strG[2]=    35;
strG[3]=    33;
strG[4]=    31;
strG[5]=    29;
strG[6]=    28;
strG[7]=    26;
strG[8]=    25;
strG[9]=    23;
strG[10]=   22;
strG[11]=   21;
strG[12]=   19;

//DelayLengthB =

strB[0]=    31;
strB[1]=    29;
strB[2]=    28;
strB[3]=    26;
strB[4]=    25;
strB[5]=    23;
strB[6]=    22;
strB[7]=    21;
strB[8]=    19;
strB[9]=    18;
strB[10]=   17;
strB[11]=   16;
strB[12]=   15;

//DelayLengthHE =

strHE[0]=    23;
strHE[1]=    22;
strHE[2]=    21;
strHE[3]=    19;
strHE[4]=    18;
strHE[5]=    17;
strHE[6]=    16;
strHE[7]=    15;
strHE[8]=    14;
strHE[9]=    14;
strHE[10]=   13;
strHE[11]=   12;
strHE[12]=   11;

//initialize Chords
/*
Our guitar is essentially a chord player. With 5 fingers of our flex glove we can have up to 32 different encodings of different chords we can play. For our demo, we encoded 24 major and minor chords built from each of the 12 notes of a chromatic scale within an octave. To make things simple we encoded the 7 chords of ‘Hotel California’ by the eagles for the first 7 chords. Following is a table of chord encodings for the flex glove. The chord numbers are binary. This means that the binary number you make with you hand correspond to the number of the chord you are playing. A bent finger correspond to a ‘1’ and the pinky is the LSB.  

1 	00001 	B minor
2 	00010 	F sharp major
3 	00011 	A major
4 	00100 	E major
5 	00101 	G major
6 	00110 	D major
7 	00111 	E minor
8 	01000 	C major
9 	01001 	C minor
10 	01010 	C sharp major
11 	01011 	C sharp minor
12 	01100 	D major
13 	01101 	D minor
14 	01110 	D# major
15 	01111 	D# minor
16 	10000 	E major
17 	10001 	E minor
18 	10010 	F Major
19 	10011 	F minor
20 	10100 	F# major
21 	10101 	F# minor
22 	10110 	G major
23 	10111 	G minor
24 	11000 	G# major
25 	11001 	G# minor
26 	11010 	A major
27 	11011 	A minor
28 	11100 	A# major
29 	11101 	A# minor
30 	11110 	B major
31 	11111 	B minor
0 	00000 	Open Strings

*/

//1st chord, all open strings
chords[0][0] = strLE[2];
chords[0][1] = strA[2];
chords[0][2] = strD[4];
chords[0][3] = strG[4];
chords[0][4] = strB[3];
chords[0][5] = strHE[2];

//2nd chord
chords[1][0] = strLE[2];
chords[1][1] = strA[4];
chords[1][2] = strD[4];
chords[1][3] = strG[3];
chords[1][4] = strB[2];
chords[1][5] = strHE[2];

//3rd chord
chords[2][0] = 0;
chords[2][1] = strA[0];
chords[2][2] = strD[2];
chords[2][3] = strG[2];
chords[2][4] = strB[2];
chords[2][5] = strHE[0];

//4th chord
chords[3][0] = strLE[0];
chords[3][1] = strA[2];
chords[3][2] = strD[2];
chords[3][3] = strG[1];
chords[3][4] = strB[0];
chords[3][5] = strHE[0];

//5th chord
chords[4][0] = strLE[3];
chords[4][1] = strA[2];
chords[4][2] = strD[0];
chords[4][3] = strG[0];
chords[4][4] = strB[0];
chords[4][5] = strHE[2];

//6st chord
chords[5][0] = 0;
chords[5][1] = 0;
chords[5][2] = strD[0];
chords[5][3] = strG[3];
chords[5][4] = strB[2];
chords[5][5] = strHE[3];

//7th chord 
chords[6][0] = strLE[0];
chords[6][1] = strA[2];
chords[6][2] = strD[2];
chords[6][3] = strG[0];
chords[6][4] = strB[0];
chords[6][5] = strHE[0];

//Commmon Chords
//8th chord
//C major
chords[7][0] = 0;
chords[7][1] = strA[3];
chords[7][2] = strD[2];
chords[7][3] = strG[0];
chords[7][4] = strB[1];
chords[7][5] = strHE[3];

//9th chord
//C minor
chords[8][0] = 0;
chords[8][1] = strA[3];
chords[8][2] = strD[1];
chords[8][3] = strG[0];
chords[8][4] = strB[1];
chords[8][5] = strHE[3];

//10th chord 
//C sharp major
chords[9][0] = 0;
chords[9][1] = strA[4];
chords[9][2] = strD[3];
chords[9][3] = strG[1];
chords[9][4] = strB[2];
chords[9][5] = strHE[1];

//11th chord
//C sharp minor
chords[10][0] = 0;
chords[10][1] = strA[4];
chords[10][2] = strD[6];
chords[10][3] = strG[6];
chords[10][4] = strB[5];
chords[10][5] = strHE[4]; 

//12th chord
//D major
chords[11][0] = 0;
chords[11][1] = strA[5];
chords[11][2] = strD[4];
chords[11][3] = strG[2];
chords[11][4] = strB[3];
chords[11][5] = strHE[2];

//13th chord
//D minor 
chords[12][0] = 0;
chords[12][1] = strA[5];
chords[12][2] = strD[7];
chords[12][3] = strG[7];
chords[12][4] = strB[6];
chords[12][5] = strHE[5];

//14th chord
//D# major 
chords[13][0] = 0;
chords[13][1] = strA[6];
chords[13][2] = strD[5];
chords[13][3] = strG[3];
chords[13][4] = strB[4];
chords[13][5] = strHE[3];

//15th chord
//D# minor
chords[14][0] = 0;
chords[14][1] = strA[6];
chords[14][2] = strD[8];
chords[14][3] = strG[8];
chords[14][4] = strB[7];
chords[14][5] = strHE[6];

//16th chord
//E major 
chords[15][0] = strLE[0];
chords[15][1] = strA[2];
chords[15][2] = strD[2];
chords[15][3] = strG[1];
chords[15][4] = strB[0];
chords[15][5] = strHE[0];

//17th chord
//E minor
chords[16][0] = strLE[0];
chords[16][1] = strA[2];
chords[16][2] = strD[2];
chords[16][3] = strG[0];
chords[16][4] = strB[0];
chords[16][5] = strHE[0];

//18th chord
//F Major
chords[17][0] = strLE[1];
chords[17][1] = strA[3];
chords[17][2] = strD[3];
chords[17][3] = strG[2];
chords[17][4] = strB[1];
chords[17][5] = strHE[1];

//19th chord
//F minor
chords[18][0] = strLE[1];
chords[18][1] = strA[3];
chords[18][2] = strD[3];
chords[18][3] = strG[1];
chords[18][4] = strB[1];
chords[18][5] = strHE[1];

//20th chord
//F# major
chords[19][0] = strLE[2];
chords[19][1] = strA[4];
chords[19][2] = strD[4];
chords[19][3] = strG[3];
chords[19][4] = strB[2];
chords[19][5] = strHE[2];

//21st chord
//F# minor
chords[20][0] = strLE[2];
chords[20][1] = strA[4];
chords[20][2] = strD[4];
chords[20][3] = strG[2];
chords[20][4] = strB[2];
chords[20][5] = strHE[2];

//22nd chord
//G major
chords[21][0] = strLE[3];
chords[21][1] = strA[2];
chords[21][2] = strD[0];
chords[21][3] = strG[0];
chords[21][4] = strB[3];
chords[21][5] = strHE[3];

//23rd chord
//G minor
chords[22][0] = strLE[3];
chords[22][1] = strA[5];
chords[22][2] = strD[5];
chords[22][3] = strG[3];
chords[22][4] = strB[3];
chords[22][5] = strHE[3];

//24th chord
//G# major
chords[23][0] = strLE[4];
chords[23][1] = strA[6];
chords[23][2] = strD[6];
chords[23][3] = strG[5];
chords[23][4] = strB[4];
chords[23][5] = strHE[4];

//25th chord
//G# minor
chords[24][0] = strLE[4];
chords[24][1] = strA[6];
chords[24][2] = strD[6];
chords[24][3] = strG[4];
chords[24][4] = strB[4];
chords[24][5] = strHE[4];

//26st chord
//A major
chords[25][0] = 0;
chords[25][1] = strA[0];
chords[25][2] = strD[2];
chords[25][3] = strG[2];
chords[25][4] = strB[2];
chords[25][5] = strHE[0];

//27th chord
//A minor
chords[26][0] = 0;
chords[26][1] = strA[0];
chords[26][2] = strD[2];
chords[26][3] = strG[2];
chords[26][4] = strB[1];
chords[26][5] = strHE[0];

//28th chord
//A# major
chords[27][0] = 0;
chords[27][1] = strA[1];
chords[27][2] = strD[3];
chords[27][3] = strG[3];
chords[27][4] = strB[3];
chords[27][5] = strHE[1];

//29th chord
//A# minor
chords[28][0] = 0;
chords[28][1] = strA[1];
chords[28][2] = strD[3];
chords[28][3] = strG[3];
chords[28][4] = strB[2];
chords[28][5] = strHE[1];

//30th chord
//B major
chords[29][0] = 0;
chords[29][1] = strA[2];
chords[29][2] = strD[4];
chords[29][3] = strG[4];
chords[29][4] = strB[4];
chords[29][5] = strHE[2];

//31st chord
//B minor
chords[30][0] = 0;
chords[30][1] = strA[2];
chords[30][2] = strD[4];
chords[30][3] = strG[4];
chords[30][4] = strB[3];
chords[30][5] = strHE[2];

//initialize string delay times     
strDelay = 18; 
strLEDelay = 0;
strADelay = strDelay;
strDDelay = strDelay*2;
strGDelay = strDelay*3;
strBDelay = strDelay*4;
strHEDelay = strDelay*5;

    

  //input output directions for ports
  DDRD = 0xff;
  DDRC = 0;
  PORTD = 0x00;
  DDRB = 0xff;
  DDRA = 0x00;
 //init timer2 
  TCCR2 = 0b00000010;

  TIMSK = 0b01000000 ;
  count = countMAX;
  count2 = count2MAX;
  count3 = count3MAX;
  time = time2 = time3 = 0;

 
  //set up the ADC
  ADMUX = 0b11100000;
  ADCSR = 0b11000111;

  //zero outputs
  outputLE =0;
  outputA = 0;
  outputD = 0;
  outputG = 0;
  outputB = 0;
  outputHE = 0;

  //init mute which controls which strings are muted 
  mute = 0xff;

  //init delay lines
  for(i=0; i<DelayLengthLE+1; i++)
  DelayLE[i] = 0;

  for(i=0; i<DelayLengthHE+1; i++)
  DelayHE[i] = 0;

  for(i=0; i<DelayLengthA+1; i++)
  DelayA[i] = 0;

  for(i=0; i<DelayLengthD+1; i++)
  DelayD[i] = 0;

  for(i=0; i<DelayLengthG+1; i++)
  DelayG[i] = 0;

  for(i=0; i<DelayLengthB+1; i++)
  DelayB[i] = 0;

 //start interrupt
  #asm
  sei
  #endasm

  while(1)
  begin
       //every 10 ms we look at inputs from accelerometer and glove and determine whether a sound should be played 
       if (time3)
       begin
         time3 =0;
         shiftedPA = PINA>>2; //We added accelerometer input after we got the glove working so we had to shift the glove inputs over 
         mute = (~shiftedPA)&0x1f;
         PORTD = ~mute; //display chord position on the LEDs
        if((mute>30) || (mute <=0)) // only care about valid chord inputs, if we encounter invalid chord input we play open strings 
       begin 
         chord[0] = strLE[0];
         chord[1] = strA[0];
         chord[2] = strD[2];
         chord[3] = strG[0];
         chord[4] = strB[0];
         chord[5] = strHE[0];
       end
       else
       begin 
         for(i = 0; i<6; i++)  chord[i] = chords[mute-1][i]; //for valid chord inputs we assign correct delay line lengths to 'chord'
       end

         
        //update delay line lengths 
         DelayLengthLE = chord[0];
         DelayLengthA = chord[1];
         DelayLengthD = chord[2];
         DelayLengthG = chord[3];
         DelayLengthB = chord[4];
         DelayLengthHE = chord[5];

          if( play != 0)
          begin

            time =0;
            time2 = 0;

            TCCR0 = 0b01101001;
            if (play > 0)
            begin
              upStrum = 1; // for our demo we only used upStrums so we dont have to swing the accelerometer as hard 
              play = 0; //reset play to debounce the accelerometer input
            end

            //initiate burst
            for (i = 0; i < DelayLengthLE; i++)
            burst[i] = rand();
            
            /*
	For each string we first check to see that there is a strum and then that its not muted
	only then do we start a new synthesis for that string 
	*/
            //LE string
            if((upStrum | dnStrum) && chord[0]!=0)
            begin

            inLE = 0;
            outLE = DelayLengthLE-1;
            counterLE =0;
            end//LE string

            //A string
            if((upStrum | dnStrum) && chord[1]!=0)
            begin

            inA = 0;
            outA = DelayLengthA-1;
            counterA =0;
            end//A string

            //D string
            if((upStrum | dnStrum) && chord[2]!=0)
            begin

            inD = 0;
            outD = DelayLengthD-1;
            counterD =0;
            end//D string

            //G string
            if((upStrum | dnStrum) && chord[3]!=0)
            begin

            inG = 0;
            outG = DelayLengthG-1;
            counterG =0;
            end//G string

            //B string
            if((upStrum | dnStrum) && chord[4]!=0)
            begin
            inB = 0;
            outB = DelayLengthB-1;
            counterB =0;
            end

            //HE string
            if((upStrum | dnStrum) && chord[5]!=0)
            begin
            inHE = 0;
            outHE = DelayLengthHE-1;
            counterHE =0;
            end

           //turn output on so the interrupt can output a sound
            output = 1;
           
         end //end if(play != 0)

  end //end if(count ==2000)
  end //end while(1)
end//end main